﻿
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.String

Public Class AccesoDatos

#Region " Variables Locales "

    Private sCadConn As String = ConfigurationManager.ConnectionStrings("SistemaNaviero").ToString()

    Private thParametros As Hashtable       ' Tabla que contendrá los parametros de salida del procedimiento almacenado invocado
    Private oCnnTrx As Conexion = Nothing   ' Objeto coneccion que maneja una transacción

#End Region

#Region " Constructores "

    'Public Sub New(ByVal CadConn As String)
    '    sCadConn = CadConn
    'End Sub

    Public Sub New()

    End Sub

    ' Con transacción
    Public Sub New(ByVal CadConn As String, ByRef oTrx As Transaccion, ByRef bExito As Boolean, ByRef sMensaje As String)

        bExito = False
        sMensaje = ""

        Try
            sCadConn = CadConn

            oCnnTrx = New Conexion(sCadConn)

            sMensaje = oCnnTrx.Open()

            If sMensaje.Trim.Length > 0 Then Exit Sub

            oTrx = New Transaccion(oCnnTrx.BeginTransaction)

            bExito = True

        Catch ex As Exception

            sMensaje = ex.Message.ToString()

            Try
                If Not oTrx Is Nothing Then oTrx.RollBack()

            Catch exTrx As Exception

            End Try

        End Try

    End Sub

    Protected Overrides Sub Finalize()

        thParametros = Nothing

        MyBase.Finalize()

    End Sub

#End Region

#Region " Propiedades "

    ' Devuelve el numero de parametros de salida del procedimiento almacenado invocado
    Public ReadOnly Property NumParamOut() As Integer
        Get
            If thParametros Is Nothing Then
                Return 0
            Else
                Return thParametros.Count
            End If
        End Get
    End Property

    ' Devuelve el parametro de salida del procedimiento almacenado invocado
    Public ReadOnly Property Parametro(ByVal sKey As Object) As Object
        Get
            If thParametros Is Nothing Then
                Return Nothing
            Else
                If thParametros.Contains(sKey) Then
                    Return thParametros.Item(sKey)
                Else
                    Return Nothing
                End If
            End If
        End Get
    End Property

#End Region

#Region " Acciones "

    'Función que devuelve un DataSet a partir de una sentencia SQL.
    Public Function DevuelveDataSet(ByVal sSql As String, ByRef bExito As Boolean, ByRef sMensaje As String) As DataSet

        bExito = False
        sMensaje = ""

        Try
            Dim oCnn As New Conexion(sCadConn)
            Dim oDs As New DataSet
            Dim oSda As New SqlDataAdapter
            Dim oCmd As New SqlCommand(sSql, oCnn.Conexion)

            oCmd.CommandType = System.Data.CommandType.Text
            oCmd.CommandTimeout = 0
            oCnn.Open()

            oSda.SelectCommand = oCmd

            oSda.Fill(oDs)

            bExito = True
            oCnn.Close()

            oCnn = Nothing
            oCmd = Nothing

            Return oDs

        Catch ex As Exception
            sMensaje = ex.Message.ToString()
            'Throw New Exception("Error al obtener los datos.")
            Return Nothing
        End Try

    End Function

    'Función que devuelve un DataSet invocando un Procedimiento Almacenado.
    Public Function DevuelveDataSet(ByVal sNombProcedimiento As String, ByRef bExito As Boolean, ByRef sMensaje As String, ByVal ParamArray Args() As Object) As DataSet

        bExito = False
        sMensaje = ""

        Try
            Dim i As Integer
            Dim oCnn As New Conexion(sCadConn)
            Dim oDs As New DataSet
            Dim oSda As New SqlDataAdapter
            Dim oCmd As New SqlCommand(sNombProcedimiento, oCnn.Conexion)

            oCmd.CommandType = System.Data.CommandType.StoredProcedure
            oCmd.CommandTimeout = 0
            oCnn.Open()

            System.Data.SqlClient.SqlCommandBuilder.DeriveParameters(oCmd)

            If Not Args Is Nothing Then
                For i = 0 To Args.Length - 1
                    oCmd.Parameters(i + 1).Value = Args(i).value
                Next
            End If

            oSda.SelectCommand = oCmd

            oSda.Fill(oDs)

            bExito = True
            oCnn.Close()

            oCnn = Nothing
            oCmd = Nothing

            Return oDs

        Catch ex As Exception
            sMensaje = ex.Message.ToString()
            'Throw New Exception("Error al obtener los datos.")
            Return Nothing
        End Try

    End Function

    'Función que devuelve un DataSet usando una Transacción.
    Public Function DevuelveDataSet(ByVal oTrx As Transaccion, ByVal sSql As String, ByRef bExito As Boolean, ByRef sMensaje As String) As DataSet

        bExito = False
        sMensaje = ""

        Try
            Dim oDs As New DataSet
            Dim oSda As New SqlDataAdapter
            Dim oCmd As New SqlCommand(sSql, oCnnTrx.Conexion, oTrx.Transaccion)

            oCmd.CommandType = System.Data.CommandType.Text
            oCmd.CommandTimeout = 0
            oSda.SelectCommand = oCmd

            oSda.Fill(oDs)

            bExito = True

            oCmd = Nothing

            Return oDs

        Catch ex As Exception
            sMensaje = ex.Message.ToString()
            'Throw New Exception("Error al obtener los datos.")
            Return Nothing
        End Try

    End Function

    'Función que devuelve un DataTable a partir de una sentencia SQL.
    Public Function DevuelveDataTable(ByVal sSql As String, ByRef bExito As Boolean, ByRef sMensaje As String) As DataTable
        Dim oDs As DataSet = DevuelveDataSet(sSql, bExito, sMensaje)

        If bExito Then
            Return oDs.Tables(0).Copy
        Else
            Return Nothing
        End If

    End Function

    'Función que devuelve un DataTable invocando un Procedimiento Almacenado.
    Public Function DevuelveDataTable(ByVal sNombProcedimiento As String, ByRef bExito As Boolean, ByRef sMensaje As String, ByVal ParamArray Args() As Object) As DataTable
        Dim oDs As DataSet = DevuelveDataSet(sNombProcedimiento, bExito, sMensaje, Args)

        If bExito Then
            Return oDs.Tables(0).Copy
        Else
            Return Nothing
        End If

    End Function

    'Función que devuelve un DataTable usando una Transacción.
    Public Function DevuelveDataTable(ByVal oTrx As Transaccion, ByVal sSql As String, ByRef bExito As Boolean, ByRef sMensaje As String) As DataTable
        Dim oDs As DataSet = DevuelveDataSet(oTrx, sSql, bExito, sMensaje)

        If bExito Then
            Return oDs.Tables(0).Copy
        Else
            Return Nothing
        End If

    End Function

    'Procedimiento que ejecuta una Sentencia  SQL.
    Public Sub EjecutaSQL(ByVal sSql As String, ByRef bExito As Boolean, ByRef sMensaje As String)

        bExito = False
        sMensaje = ""

        Try
            Dim oCnn As New Conexion(sCadConn)
            Dim oCmd As New SqlCommand(sSql, oCnn.Conexion)

            oCmd.CommandType = System.Data.CommandType.Text
            oCmd.CommandTimeout = 0
            oCnn.Open()

            oCmd.ExecuteNonQuery()

            bExito = True
            oCnn.Close()

            oCnn = Nothing
            oCmd = Nothing

        Catch ex As Exception
            sMensaje = ex.Message.ToString()
            'Throw New Exception("No se pudo ejecutar la instrucción.")
        End Try

    End Sub

    'Procedimiento que ejecuta una Sentencia SQL usando una Transacción.
    Public Sub EjecutaSQL(ByVal oTrx As Transaccion, ByVal sSql As String, ByRef bExito As Boolean, ByRef sMensaje As String)

        bExito = False
        sMensaje = ""

        Try
            Dim oCmd As New SqlCommand(sSql, oCnnTrx.Conexion, oTrx.Transaccion)

            oCmd.CommandType = System.Data.CommandType.Text
            oCmd.CommandTimeout = 0
            oCmd.ExecuteNonQuery()

            bExito = True

            oCmd = Nothing

        Catch ex As Exception
            sMensaje = ex.Message.ToString()
            'Throw New Exception("No se pudo ejecutar la instrucción.")
        End Try

    End Sub

    'Procedimiento que ejecuta un Procedimiento Almacenado con parámetros (Si el procedimiento almacenado tiene parametros de salida, los devuelve en una tabla Hash).
    Public Sub EjecutaSP(ByVal NombreSP As String, ByRef bExito As Boolean, ByRef sMensaje As String, ByVal ParamArray Args() As SqlParameter)

        bExito = False
        sMensaje = ""

        Try
            Dim oCnn As New Conexion(sCadConn), i As Integer
            Dim oCmd As New SqlCommand(NombreSP, oCnn.Conexion)

            oCmd.CommandType = System.Data.CommandType.StoredProcedure
            'oCmd.CommandTimeout = 4111
            oCnn.Open()

            System.Data.SqlClient.SqlCommandBuilder.DeriveParameters(oCmd)

            For i = 0 To Args.Length - 1
                oCmd.Parameters(i + 1).Value = Args(i).Value
            Next

            oCmd.ExecuteNonQuery()

            bExito = True
            oCnn.Close()

            thParametros = New Hashtable
            thParametros.Clear()

            ' guardando los parametros de salida del procedimiento almacenado 
            For i = 0 To Args.Length
                If (oCmd.Parameters(i).Direction = ParameterDirection.InputOutput) Or (oCmd.Parameters(i).Direction = ParameterDirection.Output) Or (oCmd.Parameters(i).Direction = ParameterDirection.ReturnValue) Then
                    thParametros.Add(oCmd.Parameters(i).ParameterName, oCmd.Parameters(i).Value)
                End If
            Next

            oCnn = Nothing
            oCmd = Nothing

        Catch ex As Exception
            sMensaje = ex.Message.ToString()
            'Throw New Exception("No se pudo ejecutar la instrucción")
        End Try

    End Sub

    Public Sub EjecutaEnLoteSP(ByVal NombreSP As String, ByRef bExito As Boolean, ByRef sMensaje As String, ByVal ParamArray Args() As SqlParameter)

        bExito = False
        sMensaje = ""

        Try
            Dim oCnn As New Conexion(sCadConn), i As Integer
            Dim oCmd As New SqlCommand(NombreSP, oCnn.Conexion)

            oCmd.CommandType = System.Data.CommandType.StoredProcedure
            oCmd.CommandTimeout = 0  ' Se pone el tiempo de espera indefinido

            oCnn.Open()

            System.Data.SqlClient.SqlCommandBuilder.DeriveParameters(oCmd)

            For i = 0 To Args.Length - 1
                oCmd.Parameters(i + 1).Value = Args(i).Value
            Next

            oCmd.ExecuteNonQuery()

            bExito = True
            oCnn.Close()

            thParametros = New Hashtable
            thParametros.Clear()

            ' guardando los parametros de salida del procedimiento almacenado 
            For i = 0 To Args.Length
                If (oCmd.Parameters(i).Direction = ParameterDirection.InputOutput) Or (oCmd.Parameters(i).Direction = ParameterDirection.Output) Or (oCmd.Parameters(i).Direction = ParameterDirection.ReturnValue) Then
                    thParametros.Add(oCmd.Parameters(i).ParameterName, oCmd.Parameters(i).Value)
                End If
            Next

            oCnn = Nothing
            oCmd = Nothing

        Catch ex As Exception
            sMensaje = ex.Message.ToString()
            'Throw New Exception("No se pudo ejecutar la instrucción")
        End Try

    End Sub

    'Cierra la conexion (asociada a una Transacción) y la libera
    Public Sub Dispose()

        If Not oCnnTrx Is Nothing Then oCnnTrx.Close()

        oCnnTrx = Nothing

    End Sub

#End Region

End Class
